﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using ColdSun.Commons.Configs;
using ColdSun.Commons.Entities;
using ColdSun.Commons;
using System.Reflection;

using Microsoft.Office.Interop.Excel;
using Microsoft.Office.Interop.Word;
using System.Runtime.InteropServices;
using ColdSun.Framework;
using System.Globalization;

namespace ColdSun.Services
{
    public class AccountService
    {
        private static AccountService serviceInstance = null;
        private List<Account> accounts = null;
        private List<Account> settlementAccounts = null;
        private string accountFile = null;

        public static AccountService GetInstance(string followingFile, DateTime fromDate, DateTime toDate)
        {
            if (serviceInstance == null || !serviceInstance.accountFile.Equals(followingFile, StringComparison.OrdinalIgnoreCase))
            {
                serviceInstance = new AccountService(followingFile, fromDate, toDate);
            }
            return serviceInstance;
        }

        public AccountService(string followingFile, DateTime fromDate, DateTime toDate)
        {
            Workbook currentWorkbook = null;
            Worksheet currentWorksheet = null;
            Microsoft.Office.Interop.Excel.Application excelApplication = null;
            try
            {
                if (!File.Exists(followingFile))
                {
                    Logger.Info(string.Format("Get Account Service -  The following file <{0}> is not existed", followingFile));
                    return;
                }

                Logger.Info(string.Format("Get Account Service -  The following file from {0}", followingFile));
                this.accountFile = followingFile;
                excelApplication = new Microsoft.Office.Interop.Excel.Application();
                currentWorkbook = excelApplication.Workbooks.Open(followingFile);
                currentWorksheet = (Worksheet)currentWorkbook.Worksheets.get_Item(1);
                Logger.Info(string.Format("Get Account Service -  The following file from sheet {0}", currentWorksheet.Name));

                int rowIndex = 2;
                accounts = new List<Account>();
                while (true)
                {
                    string cif = string.Format("{0}", currentWorksheet.get_Range(Utilities.Cell("D", rowIndex)).Value);
                    string otherColumn = string.Format("{0}", currentWorksheet.get_Range(Utilities.Cell("O", rowIndex)).Value);
                    
                    if (string.IsNullOrEmpty(cif) && string.IsNullOrEmpty(otherColumn))
                    {
                        Logger.Info(string.Format("Get Account Service - End of row {0}", rowIndex));
                        break;
                    }
                    
                    if (!string.IsNullOrEmpty(cif))
                    {
                        Account account = new Account();
                        account.CIF = cif;
                        account.AccountID = string.Format("{0}", currentWorksheet.get_Range(Utilities.Cell("E", rowIndex)).Value);
                        account.AccountName = string.Format("{0}", currentWorksheet.get_Range(Utilities.Cell("F", rowIndex)).Value);
                        account.ContractID = string.Format("{0}", currentWorksheet.get_Range(Utilities.Cell("G", rowIndex)).Value);
                        account.ThoiHanVay = string.Format("{0}", currentWorksheet.get_Range(Utilities.Cell("I", rowIndex)).Value);
                        account.TaiSan = string.Format("{0}", currentWorksheet.get_Range(Utilities.Cell("M", rowIndex)).Value);
                        //account.SettlementDate = "";
                        string settlementDateString = string.Format("{0}", currentWorksheet.get_Range(Utilities.Cell("X", rowIndex)).Value).ToLower().Trim();
                        if (!string.IsNullOrEmpty(settlementDateString))
                        {
                            if (settlementDateString.Contains("tất toán") || settlementDateString.Contains("tat toan") || settlementDateString.Contains("close"))
                            {
                                settlementDateString = settlementDateString.Replace("tất toán ngày", "").Replace("tat toan ngay", "").Replace("close ngày", "").Trim();
                                settlementDateString = settlementDateString.Replace("tất toán", "").Replace("tat toan", "").Replace("close", "").Trim();
                                settlementDateString = settlementDateString.Replace(".", "/").Replace(" ", "");
                                CultureInfo provider = CultureInfo.InvariantCulture;
                                try
                                {
                                    DateTime settlementDate = DateTime.ParseExact(settlementDateString, "d/M/yyyy", provider);
                                    account.SettlementDate = settlementDate;
                                    account.SettlementIndex = rowIndex;
                                    Logger.Info(string.Format("Account {0} has settelment date {1}", account.CIF, account.SettlementDate));

                                    if (settlementDate.Date >= fromDate.Date && settlementDate.Date <= toDate.Date)
                                    {
                                        if (settlementAccounts == null)
                                        {
                                            settlementAccounts = new List<Account>();
                                        }
                                        settlementAccounts.Add(account);
                                    }
                                }
                                catch { }
                            }
                        }
                        accounts.Add(account);
                    }
                    rowIndex++;
                }
            }
            catch (Exception ex)
            {
                Logger.Error("Get Account Service", ex);
                return;
            }
            finally
            {
                GC.Collect();
                GC.WaitForPendingFinalizers();
                ReleaseComObjectService.ReleaseComObject(currentWorksheet);
                ReleaseComObjectService.ReleaseWorkbookObject(currentWorkbook);
                ReleaseComObjectService.ReleaseExcelApplicationObject(excelApplication);
            }
        }

        public Account GetAccount(string cif)
        {
            if (this.accounts == null)
            {
                return null;
            }
            return this.accounts.Find(x => x.CIF == cif);
        }

        public List<Account> GetSettlementAccount
        {
            get
            {
                return settlementAccounts;
            }
        }
    }
}
